<%@ Page Language="VB" MasterPageFile="~/masterpages/dev.master" AutoEventWireup="false" CodeFile="datamanager_code.aspx.vb" Inherits="dev_datamanager_code" title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<h2>Data Abstraction Implementation</h2>

<p>
    I've written some tentative code for my data abstraction framework, which I'll be referring 
    to as the DataManager.
</p>
<p>
    The DataManager contains 3 classes:
</p>
<ul>
    <li>
        <p>
        <code>DataAccess.DataManager&lt;RowType&gt;</code>, a generic, abstract class that builds 
        all the queries for programmers. <code>RowType</code> must descend DataManagerRow. Any
        table class which uses the DataManager must inherit from this class.
        </p>
        <p>
            This class has a few important methods:
        </p>
        <ul>
            <li>
                <code>RowType GetItem(long id)</code>. Returns a single DataManagerRow, where
                <code>id</code> is an id field in a table.
            </li>
            <li>
                <code>List&lt;RowType&gt; GetItems()</code>. Returns a list of DataManagerRow
                objects.
            </li>
            <li>
                <code>void AddParam(string paramname, object value)</code>. Adds a where clause to
                filter results in a query. Call AddParam as many times as needed.
            </li>
            <li>
                <code>void AddSort(string colname, Sort direction)</code>. Sort is an enum which has
                values Sort.ASC, and Sort.DESC. This adds an ORDER BY clause to the query. Call
                AddSort as many times as needed.
            </li>
            <li>
                <code>void Insert(RowType Item)</code>. Inserts a new record in the table. Item is 
                passed by reference; after the item is inserted, Item.ID contains the unique ID of the
                record.
            </li>
            <li>
                <code>void Update(RowType Item)</code>. Commits changes to Item to the database.
            </li>
        </ul>
        <p>
        This class contains 2 abstract methods and 1 abstract property which must be implemented:
        </p>
        <ul>
            <li>
                <code>string TableName {get;}</code>. The name of a table in the database.
            </li>
            <li>
                <code>void CopyToItem(SqlDataReader reader, RowType Item)</code>. 
                The Data Manager returns records in a forward-only datareader. It calls CopyToItem for each
                record in the datareader. All the properties of Item should be assigned from the reader object.
            </li>
            <li>
                <code>void CopyFromItem(RowType Item)</code>. Use the add param method to copy properties
                from an Item back to the database.
            </li>
        </ul>
    </li>
    <li>
        <p>
        <code>DataAccess.DataManagerRow</code>, the class which all row objects must inherit from.
        </p>
    </li>
    <li>
        <p>
        <code>DataAccess.ObjectPool&lt;RowType&gt;</code>, by the data manager for object pooling.
        You don't have to do anything with this class, but just know its there. (This 
        isn't a object pool in the strict sense of the word, its just a glorified hashtable.)
        </p>
    </li>
</ul>

<p>
Here is the code for the data manager:<br />
<asp:HyperLink runat="server" ID="Hyperlink1"
    NavigateUrl="~/dev/DataManager.cs.txt" Text="DataAccess.DataManager" />
</p>
<p>
The code above is tentative and likely to change. I plan to add a method that will automatically
page results <a href="http://www.4guysfromrolla.com/webtech/042606-1.shtml">using this
efficient algorithm</a>. I'm also going to add a method that takes in a SqlCommand spits out a 
List&lt;RowType&gt;, just for those occasions when a custom query is genuinely appropriate.
</p>

<p>
Here are some sample classes that use the data manager.<br />
    - <asp:HyperLink runat="server" ID="Hyperlink2"
    NavigateUrl="~/dev/Users.cs.txt" Text="DataAccess.Users" /><br />
    - <asp:HyperLink runat="server" ID="Hyperlink3"
    NavigateUrl="~/dev/Articles.cs.txt" Text="DataAccess.Articles" /><br />
    - <asp:HyperLink runat="server" ID="Hyperlink4"
    NavigateUrl="~/dev/Categories.cs.txt"  Text="DataAccess.Categories" />
</p>

<p>
    The classes above are copied verbatim from a new website I'm creating. The classes represent
    a kind of blog: I have users, which are associated to articles, and articles are associated
    with categories, and categories are associated with other categories (in parent-child fashion).
</p>

<p>
    The classes above are implemented using a 
    <a href="http://msdn2.microsoft.com/en-us/library/ms998558.aspx">singleton design pattern</a>,
    so I can return a list of users without having to instantiate the Users class.
</p>

<p>
    The datamanager is a mix of generics, abstract classes, 
    singletons, datareaders, and object pooling; it should perform well and still be
    easy to use.
</p>

</asp:Content>

